package yxy.game.pm2.command.resonate;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import yxy.cherry.game.base.message.MessageEmitterHandler;
import yxy.cherry.game.base.message.annotation.MessageSource;
import yxy.cherry.game.base.message.annotation.MessageType;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Format;
import yxy.game.pm2.bean.Hero;
import yxy.game.pm2.command.Command;
import yxy.game.pm2.message.ResonateMessage;
import yxy.game.pm2.module.battle.BattleHandle;
import yxy.game.pm2.module.hero.FormatHandle;
import yxy.game.pm2.module.hero.HeroHandle;
import yxy.game.pm2.module.resonate.ResonateHandle;
import yxy.game.pm2.module.resonate.ResonateHeroMsg;
import yxy.game.pm2.module.resonate.ResonateModule;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author ljb
 * @name ResonateRetreatOrChange
 * @descrition 共鸣系统撤退或替换（上阵武将或共鸣的武将）
 * @since 2022-07-27
 */
@MessageType(proto = Command.ResonateRetreatOrChange, classtype = ResonateMessage.ResonateRetreatOrChangeRequest.class)
public class CMD_ResonateRetreatOrChange extends Command<ResonateMessage.ResonateRetreatOrChangeRequest> {

    @Override
    public void execute(MessageSource messageSource, ResonateMessage.ResonateRetreatOrChangeRequest request) {
        String playerCode = messageSource.getTag();
        int type = request.getType();//1：场上武将撤退   2：场上武将替换/上阵  3：共鸣的武将撤退  4：共鸣的武将替换/上阵
        String position = request.getPosition();
        String resonateHeroCode = request.getResonateHeroId();//共鸣的武将code
        String changeHeroCode = request.getChangeHeroId();//替换的武将code
        int field = request.getField();//共鸣武将的位置
        ResonateMessage.ResonateRetreatOrChangeResponse.Builder response = ResonateMessage.ResonateRetreatOrChangeResponse.newBuilder();

        try {
            ResonateModule module = ResonateModule.get(playerCode);
            if (module == null) {
                send(messageSource, response, Result.DataError);
                return;
            }

            Result result = null;
            switch (type) {
                case 1:
                    result = aboveHeroRetreat(module, position, playerCode);//场上武将撤退
                    break;
                case 2:
                    result = aboveHeroReplace(module, position, changeHeroCode, playerCode);//场上武将替换/上阵
                    break;
                case 3:
                    result = resonateHeroRetreat(module, resonateHeroCode, playerCode);//共鸣的武将撤退
                    break;
                case 4:
                    result = resonateHeroReplace(module, field, resonateHeroCode, changeHeroCode, playerCode);//共鸣的武将替换/上阵
                    break;
                default:
                    result = Result.DataError;
                    break;
            }

            //返回
            response.addAllAboveHeros(ResonateHandle.getAboveHeroList(module));//场上武将
            response.addAllResonateHeros(ResonateHandle.getResonateHeros(module));//共鸣武将
            response.setType(type);//类型

            send(messageSource, response, result);
        } catch (Exception e) {
            e.printStackTrace();
            send(messageSource, response, Result.DataError);
        }
    }

    private void send(MessageSource messageSource, ResonateMessage.ResonateRetreatOrChangeResponse.Builder response, Result result) {
        response.setResult(result.packResult());
        MessageEmitterHandler.getInstance().send(messageSource, response.build());
    }

    /**
     * 上阵武将撤退
     *
     * @param module
     * @param position
     * @return
     */
    private Result aboveHeroRetreat(ResonateModule module, String position, String playerCode) {
        Boolean open = module.getOpen();//如果本来就不满6个，状态应为不开启，不需要重新算战力

        //撤退，共鸣系统失效
        HashMap<String, ResonateHeroMsg> aboveHeros = module.getAboveHeros();
        aboveHeros.remove(position);

        //如果是从生效状态变成不生效状态，即本来6个，撤退其中一个，需要重新算战力
        if (open) {
            ResonateHandle resonateHandle = new ResonateHandle();
            BattleHandle battleHandle = new BattleHandle();
            resonateHandle.unOpenUpdate(module, playerCode);
            battleHandle.powerUpdate(playerCode);
            module.setOpen(false);
        }

        module.set();
        return Result.Success;
    }

    /**
     * 上阵武将替换/上阵
     *
     * @param module
     * @param position
     * @param changeHeroCode
     * @return
     */
    private Result aboveHeroReplace(ResonateModule module, String position, String changeHeroCode, String playerCode) {
        Hero hero = Hero.get(playerCode, changeHeroCode);
        if (hero == null) return Result.HeroNotExists;//武将不存在

        //重复武将不能上阵
        HashMap<String, ResonateHeroMsg> aboveHeros = module.getAboveHeros();

        ArrayList<String> aboveHeroCodeList = ResonateHandle.getAboveHeroCodeList(module);

        ArrayList<String> resonateHeroCodeList = ResonateHandle.getResonateHeroCodeList(module);

        if (aboveHeroCodeList.contains(changeHeroCode)) return Result.ResonateConfirmAboveHeroCantRepeat;//不能是场上的武将
        if (resonateHeroCodeList.contains(changeHeroCode))
            return Result.ResonateConfirmAboveHeroCantSelectResonateHero;//不能是共鸣的武将

        //封装
        ResonateHeroMsg resonateHeroMsg = new ResonateHeroMsg();
        resonateHeroMsg.setCode(hero.getCode());
        resonateHeroMsg.setHeroId(hero.getDataId());
        resonateHeroMsg.setPosition(position);
        resonateHeroMsg.setLevel(hero.getLevel());
        resonateHeroMsg.setStar(hero.getStar());
        resonateHeroMsg.setStage(hero.getStage());

        aboveHeros.put(position, resonateHeroMsg);

        //替换或上阵，需要判断是否满足6个是否开启状态才计算战力
        if (aboveHeros.size() == 6) {
            module.setOpen(true);//系统生效
            HashMap<String, ResonateHeroMsg> minimumLevel = ResonateHandle.getMinimumLevel(module);

            ResonateHeroMsg minimumHeroMsg = null;//最低级的那个武将信息
            for (ResonateHeroMsg msg : minimumLevel.values()) {
                minimumHeroMsg = msg;
                break;
            }

            HashMap<String, Integer> map = BattleHandle.addStarAndStage(hero.getDataId(), 0, 0, minimumHeroMsg.getLevel());//计算阶级

            for (ResonateHeroMsg msg : module.getResonateHeros()) {
                if (StringUtils.isEmpty(msg.getCode())) continue;
                msg.setCode(msg.getCode());
                msg.setHeroId(msg.getHeroId());
                msg.setLevel(minimumHeroMsg.getLevel());
                msg.setStar(msg.getStar());
                msg.setStage(map.get("stage"));

                Hero msgHero = Hero.get(playerCode, msg.getCode());
                msgHero.setStage(map.get("stage"));
                msgHero.setLevel(minimumHeroMsg.getLevel());
                Hero.set(playerCode, msgHero);
            }

            //更新战力
            BattleHandle battleHandle = new BattleHandle();
            battleHandle.powerUpdate(playerCode);
        }

        module.set();
        return Result.Success;

    }


    /**
     * 共鸣武将撤退
     *
     * @param module
     * @param resonateHeroCode
     * @return
     */
    private Result resonateHeroRetreat(ResonateModule module, String resonateHeroCode, String playerCode) {
        Hero hero = Hero.get(playerCode, resonateHeroCode);
        if (hero == null) return Result.ResonateConfirmNotExist;
        ArrayList<ResonateHeroMsg> resonateHeros = module.getResonateHeros();

        //todo 共鸣没激活状态下撤退
        if (!module.getOpen()) {

            int index = -1;
            for (int i = 0; i < resonateHeros.size(); i++) {
                ResonateHeroMsg msg = resonateHeros.get(i);
                if (resonateHeroCode.equals(msg.getCode())) {
                    index = i;
                }
            }

            resonateHeros.set(index, new ResonateHeroMsg());
            module.set();
            return Result.Success;
        }

        //todo 共鸣激活状态下撤退
        int index = -1;
        for (int i = 0; i < resonateHeros.size(); i++) {
            ResonateHeroMsg msg = resonateHeros.get(i);
            if (resonateHeroCode.equals(msg.getCode())) {
                index = i;
                break;
            }
        }

        ResonateHeroMsg heroMsg = resonateHeros.get(index);
        int originalLevel = heroMsg.getOriginalLevel();
        int originalStage = heroMsg.getOriginalStage();
        hero.setLevel(originalLevel);
        hero.setStage(originalStage);
        Hero.set(playerCode, hero);
        resonateHeros.set(index, new ResonateHeroMsg());
        module.set();

        //判断是不是在队伍，更新战力
        FormatHandle formatHandle = new FormatHandle();
        ArrayList<String> list = formatHandle.formatCodesList(playerCode, Format.get(playerCode, Format.FormatType.普通));

        if (list.contains(resonateHeroCode)) {
            //重算战力
            HeroHandle heroHandle = new HeroHandle();
            heroHandle.updateHero(playerCode, hero);
            return Result.Success;
        }

        return Result.Success;
    }


    /**
     * 共鸣武将替换
     *
     * @param module
     * @param field
     * @param resonateHeroCode
     * @param changeHeroCode
     * @return
     */
    private Result resonateHeroReplace(ResonateModule module, int field, String resonateHeroCode, String changeHeroCode, String playerCode) {
        Boolean open = module.getOpen();

        if (!open || module.getAboveHeros().size() != 6) return Result.ResonateConfirmAbsenceAboveHero;

        //todo 判断cd等待时间
        if (module.cooldown(field)) {
            int lesstime = (int) Math.abs(module.getUpdateTime().get(String.valueOf(field)).getMillis() - DateTime.now().getMillis());
            return new Result(Result.ResonateConfirmTimeCD, lesstime);// 挑战冷却中
        }

        Hero changeHero = Hero.get(playerCode, changeHeroCode);//要更改的武将

        HashMap<String, ResonateHeroMsg> minimumLevelMap = ResonateHandle.getMinimumLevel(module);
        ResonateHeroMsg minimumHeroMsg = null;
        for (ResonateHeroMsg value : minimumLevelMap.values()) {
            minimumHeroMsg = value;//最低级的那个武将
            break;
        }
        HashMap<String, Integer> map = BattleHandle.addStarAndStage(changeHero.getDataId(), 0, 0, minimumHeroMsg.getLevel());//计算阶级

        ArrayList<ResonateHeroMsg> resonateHeros = module.getResonateHeros();

        ResonateHeroMsg msg = resonateHeros.get(field);

        //todo 上阵操作
        if (StringUtils.isEmpty(resonateHeroCode) && StringUtils.isNotEmpty(changeHeroCode)) {
            if (StringUtils.isNotEmpty(msg.getCode())) return Result.DataError;
        }


        //todo 替换操作
        if (StringUtils.isNotEmpty(resonateHeroCode) && StringUtils.isNotEmpty(changeHeroCode)) {
            //原武将状态变回最初状态
            Hero originalHero = Hero.get(playerCode, msg.getCode());
            originalHero.setLevel(msg.getOriginalLevel());
            originalHero.setStage(msg.getOriginalStage());
            Hero.set(playerCode, originalHero);
        }

        //修改要替换的武将状态信息
        msg.setCode(changeHero.getCode());
        msg.setHeroId(changeHero.getDataId());
        msg.setLevel(minimumHeroMsg.getLevel());
        msg.setStar(changeHero.getStar());
        msg.setStage(map.get("stage"));
        msg.setOriginalLevel(changeHero.getLevel());
        msg.setOriginalStage(changeHero.getStage());

        changeHero.setStage(map.get("stage"));
        changeHero.setLevel(minimumHeroMsg.getLevel());
        Hero.set(playerCode, changeHero);

        HashMap<String, DateTime> times = module.getUpdateTime();
        times.put(String.valueOf(field), DateTime.now().plusMinutes(ResonateModule.resonateHeroCDMinute));//更新下次能共鸣的时间
        module.set();

        //更新战力
        BattleHandle battleHandle = new BattleHandle();
        battleHandle.powerUpdate(playerCode);
        return Result.Success;
    }


}